egw_ready.js ➔ readyEventHandler   A
last analyzed

Complexity

Conditions 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
eloc 2
dl 0
loc 3
rs 10
c 0
b 0
f 0
1
/**
2
 * EGroupware clientside API object
3
 *
4
 * @license http://opensource.org/licenses/gpl-license.php GPL - GNU General Public License
5
 * @package etemplate
6
 * @subpackage api
7
 * @link http://www.egroupware.org
8
 * @author Andreas Stöckel (as AT stylite.de)
9
 * @version $Id$
10
 */
11
12
/*egw:uses
13
	egw_core;
14
	egw_utils;
15
	egw_debug;
16
*/
17
18
/**
19
 * @augments Class
20
 * @param {string} _app application name object is instanciated for
21
 * @param {object} _wnd window object is instanciated for
22
 */
23
egw.extend('ready', egw.MODULE_WND_LOCAL, function(_app, _wnd)
24
{
25
	"use strict";
26
27
	var egw = this;
28
29
	var registeredCallbacks = [];
30
	var registeredProgress = [];
31
	var readyPending = {'readyEvent': true};
32
	var readyPendingCnt = 1;
33
	var readyDoneCnt = 0;
34
	var isReady = false;
35
36
	function doReadyWaitFor() {
37
		if (!isReady)
38
		{
39
			var uid = egw.uid();
40
			readyPending[uid] = true;
41
			readyPendingCnt++;
42
43
			readyProgressChange();
44
45
			return uid;
46
		}
47
48
		this.debug('warning', 'ready has already been called!');
49
50
		return null;
51
	}
52
53
	function doReadyDone(_token) {
54
		if (typeof readyPending[_token] !== 'undefined')
55
		{
56
			delete readyPending[_token];
57
			readyPendingCnt--;
58
			readyDoneCnt++;
59
60
			readyProgressChange();
61
62
			testCallReady();
63
		}
64
	}
65
66
	function readyProgressChange()
67
	{
68
		// Call all registered progress callbacks
69
		for (var i = 0; i < registeredProgress.length; i++)
70
		{
71
			registeredProgress[i].callback.call(
72
				registeredProgress[i].context,
73
				readyDoneCnt,
74
				readyPendingCnt
75
			);
76
		}
77
78
		egw.debug('log', 'Ready events, processed %s/%s', readyDoneCnt,
79
				readyPendingCnt + readyDoneCnt);
80
	}
81
82
	function readyEventHandler() {
83
		doReadyDone('readyEvent');
84
	}
85
86
	function testCallReady()
87
	{
88
		// Check whether no further event is pending
89
		if (readyPendingCnt <= 1 && !isReady)
0 ignored issues
show
Bug introduced by
The variable isReady seems to be never initialized.
Loading history...
90
		{
91
			// If exactly one event is pending and that one is not the ready
92
			// event, abort
93
			if (readyPendingCnt === 1 && !readyPending['readyEvent'])
94
			{
95
				return;
96
			}
97
98
			// Set "isReady" to true, if readyPendingCnt is zero
99
			var isReady = readyPendingCnt === 0;
100
101
			// Call all registered callbacks
102
			for (var i = registeredCallbacks.length - 1; i >= 0; i--)
103
			{
104
				if (registeredCallbacks[i].before || readyPendingCnt === 0)
105
				{
106
					registeredCallbacks[i].callback.call(
107
						registeredCallbacks[i].context
108
					);
109
110
					// Delete the callback from the list
111
					registeredCallbacks.splice(i, 1);
112
				}
113
			}
114
		}
115
	}
116
117
	// Register the event handler for "ready" (code adapted from jQuery)
118
119
	// Mozilla, Opera and webkit nightlies currently support this event
120
	if (_wnd.document.addEventListener) {
121
		// Use the handy event callback
122
		_wnd.document.addEventListener("DOMContentLoaded", readyEventHandler, false);
123
124
		// A fallback to window.onload, that will always work
125
		_wnd.addEventListener("load", readyEventHandler, false);
126
127
	// If IE event model is used
128
	} else if (_wnd.document.attachEvent) {
129
		// ensure firing before onload,
130
		// maybe late but safe also for iframes
131
		_wnd.document.attachEvent("onreadystatechange", readyEventHandler);
132
133
		// A fallback to window.onload, that will always work
134
		_wnd.attachEvent("onload", readyEventHandler);
135
	}
136
137
	return {
138
139
		/**
140
		 * The readyWaitFor function can be used to register an event, that has
141
		 * to be marked as "done" before the ready function will call its
142
		 * registered callbacks. The function returns an id that has to be
143
		 * passed to the "readDone" function once
144
		 *
145
		 * @memberOf egw
146
		 */
147
		readyWaitFor: function() {
148
			return doReadyWaitFor();
149
		},
150
151
		/**
152
		 * The readyDone function can be used to mark a event token as
153
		 * previously requested by "readyWaitFor" as done.
154
		 *
155
		 * @param _token is the token which has now been processed.
156
		 */
157
		readyDone: function(_token) {
158
			doReadyDone(_token);
159
		},
160
161
		/**
162
		 * The ready function can be used to register a function that will be
163
		 * called, when the window is completely loaded. All ready handlers will
164
		 * be called exactly once. If the ready handler has already been called,
165
		 * the given function will be called defered using setTimeout.
166
		 *
167
		 * @param _callback is the function which will be called when the page
168
		 * 	is ready. No parameters will be passed.
169
		 * @param _context is the context in which the callback function should
170
		 * 	get called.
171
		 * @param _beforeDOMContentLoaded specifies, whether the callback should
172
		 * 	get called, before the DOMContentLoaded event has been fired.
173
		 */
174
		ready: function(_callback, _context, _beforeDOMContentLoaded) {
175
			if (!isReady)
176
			{
177
				registeredCallbacks.push({
178
					'callback': _callback,
179
					'context': _context ? _context : null,
180
					'before': _beforeDOMContentLoaded ? true : false
181
				});
182
			}
183
			else
184
			{
185
				setTimeout(function() {
186
					_callback.call(_context);
187
				}, 1);
188
			}
189
		},
190
191
		/**
192
		 * The readyProgress function can be used to register a function that
193
		 * will be called whenever a ready event is done or registered.
194
		 *
195
		 * @param _callback is the function which will be called when the
196
		 * 	progress changes.
197
		 * @param _context is the context in which the callback function which
198
		 * 	should get called.
199
		 */
200
		readyProgress: function(_callback, _context) {
201
			if (!isReady)
202
			{
203
				registeredProgress.unshift({
204
					'callback': _callback,
205
					'context': _context ? _context : null
206
				});
207
			}
208
			else
209
			{
210
				this.debug('warning', 'ready has already been called!');
211
			}
212
		},
213
214
		/**
215
		 * Returns whether the ready events have already been called.
216
		 */
217
		isReady: function() {
218
			return isReady;
219
		}
220
	};
221
222
});
223
224
225